<template>
  <div class="vue-flow-edit-menu" draggable="true" @dragstart="onDragstart" @dragend="onDragend">
    <slot name="content" :model="model">
      <span>{{ model.label }}</span>
    </slot>
    <i class="el-icon-arrow-right" v-if="!hideArrow"></i>
  </div>
</template>

<script>
import { VueFlowEditorProvider } from "@/editor/editor";
import { formatNodeModel, formatPos } from "../utils/utils";

export default {
  name: "vue-flow-edit-menu",
  inject: {
    [VueFlowEditorProvider]: {},
  },
  props: {
    model: { type: Object, require: true }, // 节点新建的时候的配置对象
    hideArrow: { type: Boolean }, // 是否隐藏箭头
  },
  data() {
    return {
      handler: {
        dragenter: (e) => {
          e.dataTransfer.dropEffect = "move";
        },
        dragover: (e) => {
          e.preventDefault();
        },
        dragleave: (e) => {
          e.dataTransfer.dropEffect = "none";
        },
        drop: async (e) => {
          let model = { ...this.model };
          formatNodeModel(model, this[VueFlowEditorProvider].props.activityConfig);

          let { id, shape, size } = model;

          shape = shape || "rect";

          id = id || String(new Date().getTime());
          if (typeof id === "function") {
            id = await id();
          }

          const { clientX, clientY } = e;
          let { x, y } = this.graph.getPointByClient(clientX, clientY);

          const { beforeAdd, afterAdd } = this[VueFlowEditorProvider].editorState.props;

          const formatData = formatPos({
            x,
            y,
            size,
            shape,
          });

          model = {
            ...model,
            id,
            shape: formatData.shape,
            size: formatData.size,
            x: formatData.x,
            y: formatData.y,
          };

          try {
            if (!!beforeAdd) {
              await beforeAdd(model, "node");
            }
            this.graph.emit("add-node:before", model);
            this.graph.add("node", model);
            this.graph.paint();
            this.graph.emit("add-node:after", model);
            if (!!afterAdd) {
              await afterAdd(model, "node");
            }
          } catch (e) {
            console.error(e);
          }
        },
      },
    };
  },
  computed: {
    graph() {
      return this[VueFlowEditorProvider].editorState.graph;
    },
    container() {
      return !!this.graph ? this.graph.get("container") : null;
    },
  },
  methods: {
    onDragstart(e) {
      e.dataTransfer.effectAllowed = "move";

      this.container.addEventListener("dragenter", this.handler.dragenter);
      this.container.addEventListener("dragover", this.handler.dragover);
      this.container.addEventListener("dragleave", this.handler.dragleave);
      this.container.addEventListener("drop", this.handler.drop);
    },
    onDragend() {
      this.container.removeEventListener("dragenter", this.handler.dragenter);
      this.container.removeEventListener("dragover", this.handler.dragover);
      this.container.removeEventListener("dragleave", this.handler.dragleave);
      this.container.removeEventListener("drop", this.handler.drop);
    },
  },
};
</script>

<style lang="scss"></style>
